﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Matrix.Common.Utility;
using Matrix.MaKaYunShang.BLL;
using Matrix.MaKaYunShang.BLL.WxPayAPI;
using Matrix.MaKaYunShang.Model;
using Matrix.MaKaYunShang.Model.Enum;
using Matrix.MaKaYunShang.Model.MatrixCloudApi;
using Matrix.MaKaYunShang.Model.Wechat;
using ThoughtWorks.QRCode.Codec;

namespace Matrix.MaKaYunShang.McMagWeb.Controllers
{
    [Authorization]
    public class ChargeController : BaseController
    {
        public ActionResult WeChatAuthorize(string returnurl)
        {
            if (Request.Url == null)
            {
                Logger.Error(
                    "ChargeController | WeChatAuthorize | The request url is null. ");
                throw new Exception(
                    "ChargeController | WeChatAuthorize | The request url is null. ");
            }

            var projectInfo = GetCurrentMatrixCloudProjectInfo(MkysMcMagMcId);
            if (projectInfo == null || projectInfo.Id == 0)
            {
                Logger.Error(
                    "ChargeController | WeChatAuthorize | Cannot get the project info from Matrix-Cloud-Center and db ");
                throw new Exception(
                    "ChargeController | WeChatAuthorize | Cannot get the project info from Matrix-Cloud-Center and db ");
            }

            var wechatInfo = GetWechatInfoByProjectInfo(projectInfo.PjMcId, projectInfo.PjSecret);

            if (wechatInfo == null || wechatInfo.Id <= 0)
            {
                Logger.Error("ChargeController | WeChatAuthorize | wechatInfo  Does not exist ");
                throw new Exception("ChargeController | WeChatAuthorize | wechatInfo  Does not exist ");
            }
            var strAuthInterfaceUrl = wechatInfo.AuthorizeUrl + "?callBackUrlEncode=" +
                                      System.Web.HttpContext.Current.Server.UrlEncode(returnurl);
            Response.Redirect(strAuthInterfaceUrl);
            return View();
        }

        public ActionResult Index()
        {
            var currentMatrixCloudProjectInfo = GetCurrentMatrixCloudProjectInfo(MkysMcMagMcId);
            if (currentMatrixCloudProjectInfo == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "项目资料不存在");
            }
            var wechatInfo = GetWechatInfoByProjectInfo(currentMatrixCloudProjectInfo.PjMcId, currentMatrixCloudProjectInfo.PjSecret);
            if (wechatInfo == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "微信公众号不存在");
            }
            WxPayConfig.APPID = wechatInfo.AppId;
            WxPayConfig.KEY = wechatInfo.PayKey;
            WxPayConfig.APPSECRET = wechatInfo.Secret;
            WxPayConfig.MCHID = wechatInfo.MchId;
            WxPayConfig.SSLCERT_PATH = wechatInfo.CertPath;
            WxPayConfig.SSLCERT_PASSWORD = wechatInfo.MchId;
            WxPayConfig.IP = ConfigurationManager.AppSettings["LocalWWWIp"];
            WxPayConfig.NOTIFY_URL = ConfigurationManager.AppSettings["NOTIFY_URL"];
            return View();
        }
        /// <summary>
        /// 支付
        /// </summary>
        /// <param name="money">金额</param>
        /// <returns></returns>
        public ActionResult Pay(int money)
        {
            var userAgent = Request.UserAgent;
            var now = DateTime.Now;
            if (money <= 0 || money > 100000)
            {
                return RedirectToAction("ErrorGeneral", "Error", new { msg = "充值金额必须为1-100000" });
            }
            if (money % 200 != 0)
            {
                return RedirectToAction("ErrorGeneral", "Error", new { msg = "充值金额必须为200元的整倍数" });
            }
            var shopSubsidiaryInfo = ShopSubsidiaryInfoBLL.Instance.GetModelByShopId(CurrentUser.ShopId);
            if (shopSubsidiaryInfo == null)
            {
                return RedirectToAction("ErrorGeneral", "Error", new { msg = "店铺信息错误" });
            }
            var newId = ShopMoneyChangeRecordBLL.Instance.Add(new ShopMoneyChangeRecord()
            {
                AddTime = now,
                AfterMoney = shopSubsidiaryInfo.AccountMoney + money,
                BeforeMoney = shopSubsidiaryInfo.AccountMoney,
                ChangeMoney = money,
                ChangeSource = (int)CloudCardEnum.MerchantMoneyChangeSource.充值,
                OperaOpenId = CurrentUser.openId,
                OperaResult = (int)CommonEnum.OperaResult.待操作,
                OperaSource = (int)CloudCardEnum.MerchantMoneyOperaSource.商家,
                OperaUserId = CurrentUser.AccountId,
                ShopId = CurrentUser.ShopId,
                MxProjectInfoId = CurrentUser.MxProjectInfoId
            });
            if (userAgent.ToLower().Contains("micromessenger"))
            {
                return RedirectToAction("JsPay", new { money, outTradeNo = newId });
            }
            return RedirectToAction("PayQRcode", new { money, outTradeNo = newId });
        }

        /// <summary>
        /// js sdk 支付
        /// </summary>
        /// <param name="money">单位分</param>
        /// <param name="outTradeNo"></param>
        /// <param name="openId">openId</param>
        /// <returns></returns>
        public ActionResult JsPay(int money, int outTradeNo, string openId = "")
        {
            if (string.IsNullOrEmpty(openId))
            {
                //授权
                return Redirect("/Charge/WeChatAuthorize?returnurl=" + HttpUtility.UrlEncode(Request.Url.AbsoluteUri));
            }
            var context = System.Web.HttpContext.Current;
            //检测是否给当前页面传递了相关参数
            if (string.IsNullOrEmpty(openId) || money < 1)
            {
                Logger.Error("JsPay|This page have not get params, cannot be inited, exit...");
                Response.Redirect("/Charge/PayFail");
            }
            //若传递了相关参数，则调统一下单接口，获得后续相关接口的入口参数
            JsApiPay jsApiPay = new JsApiPay(context)
            {
                openid = openId,
                total_fee = money
            };
            //JSAPI支付预处理
            try
            {

                WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult(openId, money * 100, outTradeNo.ToString(), "码云卡商家余额充值");
                ViewBag.WxJsApiParam = jsApiPay.GetJsApiParameters(); //获取H5调起JS API参数                    
                //在页面上显示订单信息
                Logger.Info("JsPay|wxJsApiParam : " + ViewBag.WxJsApiParam + ",订单详情" + unifiedOrderResult.ToPrintStr());
            }
            catch (Exception ex)
            {
                Logger.Error("JsPay|下单失败，请返回重试ex:" + ex);
                Response.Redirect("/Charge/PayFail");
            }
            ViewBag.Money = money;
            return View();
        }
        public ActionResult PayQRcode(int money, int outTradeNo)
        {
            if (money <= 0 || money > 100000)
            {
                return RedirectToAction("ErrorGeneral", "Error", new { msg = "充值金额必须为1-100000" });
            }
            var nativePay = new NativePay();
            ViewBag.OutTradeNoEnc = EncryptionLib.Encrypt(outTradeNo.ToString());
            ViewBag.QrCode = nativePay.GetPayUrl(outTradeNo.ToString(), "码云卡商家余额充值", money * 100, WxPayTradeType.NATIVE);
            ViewBag.Money = money;
            return View();
        }

        /// <summary>
        /// 扫码支付检测支付回调结果
        /// </summary>
        /// <param name="outTradeNoEnc">加密后的支付记录ID</param>
        public ActionResult CheckPay(string outTradeNoEnc)
        {
            var result = new Result { Status = false };
            try
            {
                var model = ShopMoneyChangeRecordBLL.Instance.GetModel(int.Parse(EncryptionLib.Decrypt(outTradeNoEnc)));
                if (model != null && model.OperaResult == (int)CommonEnum.OperaResult.操作成功)
                {
                    result.Status = true;
                    return Json(result);
                }
            }
            catch (Exception ex)
            {
                Logger.Error("ChargeController|CheckPay|ex:" + ex);
            }
            return Json(result);
        }

        public ActionResult Success()
        {
            return View();
        }

        public ActionResult PayFail()
        {
            return View();
        }

    }
}